package video.others

//扩展属性
val Float.dp
    get() = this.toString().plus("dp")


//顶层扩展函数，局限于包
fun Int.toFloat() = this.toFloat()

fun Int.toS(str: String) = str.plus(this)

fun test(str: String) {
    println(str)
}

fun invokeFun(func: (String) -> Unit, str: String) {

    func(str)
}


class Test {

    //既是成员函数也是扩展函数，所以用::表示函数引用会有歧义，不能使用:;表示，只局限于这个类使用，外部使用不了
    fun Int.toStr() = this.toString()

    fun test() {
        println(11.toStr())
    }

}

fun main() {

    //::函数引用的表示，左边的Receiver可有可无，有（成员函数左边就是成员所属类，扩展函数就是要扩展的类）
    invokeFun(::test, "test")

    //成员函数引用需要第一个参数传递成员所属的类
    (Test::test)(Test())

    //或者转成Receiver函数调用
    val testReceiver: Test.() -> Unit = Test::test
    Test().testReceiver()

    //扩展函数引用
    (Int::toFloat)(22)
    (Int::toFloat).invoke(88)


    //有无Receiver可以互相转换，将Receiver当成函数的第一个参数传递即可
    (Int::toS)(11, "test1")
    (Int::toS).invoke(11, "test2")
    11.toS("test3")

    //通过函数引用变量相互转换
    //无Receiver转有Receiver
    val testVar: String.() -> Unit = ::test
    "test4".testVar()

    //有Receiver转无Receiver
    val toSVar: (Int, String) -> String = Int::toS
    println(toSVar(100, "test5"))

    println(88f.dp)

}




